package com.mongoosehome.web.util;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.SessionFactoryUtils;

/**
 * 对Hibernate的封装
 *
 */
public class HibernateUtils {

    private static Logger logger = Logger.getLogger(HibernateUtils.class);
    /**
     * 默认的查询别名
     */
    public static String ALIAS = "_alias";

    /**
     * 创建查询对象
     *
     * @param session Hibernate的Session
     * @param query 查询语句
     * @param args 查询语句中的参数
     * @return 构建好的查询对象
     */
    public static Query createQuery(Session session, String query, Object[] args) {
        logger.debug("query=" + query);
        Query queryObj = session.createQuery(query);
        if (null != args && args.length > 0) {
            for (int i = 0; i < args.length; i++) {
                queryObj.setParameter(i, args[i]);
            }
        }
        return queryObj;
    }

    /**
     * 创建SQL查询对象
     *
     * @param session Hibernate的Session
     * @param sql sql查询语句
     * @param args 查询语句中的参数
     * @return 构建好的查询对象
     */
    public static SQLQuery createSQLQuery(Session session, String sql, Object[] args) {
        logger.debug("sql=" + sql);
        SQLQuery sqlQuery = session.createSQLQuery(sql);
        if (null != args && args.length > 0) {
            for (int i = 0; i < args.length; i++) {
                sqlQuery.setParameter(i, args[i]);
            }
        }
        return sqlQuery;
    }

    /**
     * 查询符合条件文件的总数
     *
     * @param session Hibernate的Session
     * @param sessionFactory Hibernate的SessionFactory
     * @param args 参数列表
     * @param hql
     * @param flaxWhere
     * @return 返回符合条件总的数目
     */
    public static int getFileCount(Session session, SessionFactory sessionFactory,
            String hql, Object[] args, boolean flaxWhere) {
        try {
            String hqlTemp = removeOrders(hql);
            logger.debug("after remove order by =" + hqlTemp);
            if (flaxWhere) {
                hqlTemp = removeSelects(hqlTemp);
            }
            logger.debug("after remove select info =" + hqlTemp);
            Query query = session.createQuery("select count(*) " + hqlTemp);
            if (null != args) {
                for (int i = 0; i < args.length; i++) {
                    query.setParameter(i, args[i]);
                }
            }
            return ((Number) query.uniqueResult()).intValue();
        } catch (HibernateException he) {
            he.printStackTrace();
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }


    /**
     * 剔除查询语句中的排序语句
     *
     * @param hql 查询的语句
     * @return 如果存在排序语句，则将排序语句剔除，否则返回原查询语句
     */
    private static String removeOrders(String hql) {
        if (null == hql || hql.length() == 0) {
            return "";
        }
        if (hql.indexOf("order by") < 0) {
            return hql;
        }
        return hql.substring(0, hql.indexOf("order by"));
    }

    /**
     * 剔除查询语句中的选择语句
     *
     * @param hql 查询的语句
     * @return 如果存在选择语句，则将选择语句剔除，否则返回原查询语句
     */
    private static String removeSelects(String hql) {
        if (null == hql || hql.length() == 0) {
            return "";
        }
        if (hql.indexOf("select ") < 0) {
            return hql;
        }
        if (hql.indexOf("from ") < 0) {
            return hql;
        }
        return hql.substring(hql.indexOf("from"), hql.length());
    }

    /**
     * 获取分页数据。
     * @param session
     * @param sessionFactory
     * @param currentPage      当前页
     * @param pageSize         没页的个数
     * @param query            HQL查询语句
     * @param args             参数
     * @return 
     */
    public static PageInfo getNumberPage(Session session, SessionFactory sessionFactory,
            int currentPage, int pageSize, String query, Object[] args) {
        return getNumberPage(session, sessionFactory, currentPage, pageSize, query, args, true);
    }
    
    /**
     * 获取分页数据。
     * @param session
     * @param sessionFactory
     * @param currentPage      当前页
     * @param pageSize         没页的个数
     * @param query            HQL查询语句
     * @param args             参数
     * @param flaxWhere        用select count(*) 替代select ****
     * @return 
     */
    public static PageInfo getNumberPage(Session session, SessionFactory sessionFactory,
            int currentPage, int pageSize, String query, Object[] args, boolean flaxWhere) {
        try {
            if (null == query || query.length() == 0) {
                return new PageInfo();
            }
            Query queryObj = createQuery(session, query, args);
            int totalCount = getFileCount(session, sessionFactory, query, args, flaxWhere);
            //返回分页对象
            if (totalCount < 1) {
                return new PageInfo();
            }

            PageInfo pageInfo = new PageInfo(currentPage, totalCount, pageSize);
            queryObj.setFirstResult(pageInfo.getFirstNo());
            if (pageSize > 0) {
                queryObj.setMaxResults(pageSize);
            }
            List<?> fileList = queryObj.list();
            pageInfo.setFileList(fileList);
            return pageInfo;
        } catch (HibernateException he) {
            he.printStackTrace();
            return new PageInfo();
        } finally {
            SessionFactoryUtils.releaseSession(session, sessionFactory);
        }
    }
}